﻿package org.jecat.pusher
{
	import flash.display.MovieClip ;
	import flash.events.* ;
	import flash.external.ExternalInterface ;
	import flash.net.Socket;
	import flash.net.XMLSocket;
	
	public class Receiver extends MovieClip
	{		
		public function Receiver()
		{
			m_aSocket = new Socket() ;
			m_aSocket.addEventListener("connect",onConnected) ;
			m_aSocket.addEventListener("close",onDisconnect) ;
			m_aSocket.addEventListener("socketData",onPkgReceiver) ;
			m_aSocket.addEventListener("ioError",onError) ;
			m_aSocket.addEventListener("securityError",onSecurityError) ;
			
			// swf 接口
			if (ExternalInterface.available)
			{
				ExternalInterface.addCallback("version",version) ;
				
				ExternalInterface.addCallback("connect",connect) ;
				ExternalInterface.addCallback("close",close) ;
				
				ExternalInterface.addCallback("setReceiveHandle",setReceiveHandle) ;
				ExternalInterface.addCallback("setDisconnectHandle",setDisconnectHandle) ;
				ExternalInterface.addCallback("setConnectHandle",setConnectHandle) ;
				ExternalInterface.addCallback("setErrorHandle",setErrorHandle) ;
				ExternalInterface.addCallback("setSecurityErrorHandle",setSecurityErrorHandle) ;
				
				
				ExternalInterface.call("__org_jecat_pusher_loaded") ;
			}
			
			//connect("192.168.1.211",7885,"channel=public") ;
		}
		
		public function version()
		{
			return "0.1.1" ;
		}
		
		public function connect(sServer:String,nPort:int,sRequest:String)
		{
			output("connecting "+sServer+":"+nPort+" "+sRequest+"... ...") ;
			m_sRequest = sRequest ;
			m_aSocket.connect(sServer,nPort) ;
		}
		
		public function close()
		{
			output("close") ;
			m_aSocket.close() ;
		}
		
		public function setReceiveHandle(sFuncName:String)
		{
			m_sHandleReceive = sFuncName ;
		}
		public function setDisconnectHandle(sFuncName:String)
		{
			m_sHandleDisconnect = sFuncName ;
		}
		public function setConnectHandle(sFuncName:String)
		{
			m_sHandleConnect = sFuncName ;
		}
		public function setErrorHandle(sFuncName:String)
		{
			m_sHandleError = sFuncName ;
		}
		public function setSecurityErrorHandle(sFuncName:String)
		{
			m_sHandleSecurityError = sFuncName ;
		}

		private function onDisconnect(e:Event)
		{
				output("close") ;
			if( ExternalInterface.available && m_sHandleDisconnect )
			{
				ExternalInterface.call(m_sHandleDisconnect) ;
			}
		}
		private function onConnected(e:Event)
		{
			output("onConnected:: "+m_sRequest) ;
			if( ExternalInterface.available && m_sHandleConnect )
			{
				ExternalInterface.call(m_sHandleConnect) ;
			}
			send(m_sRequest) ;
		}
		private function onPkgReceiver(e:Event)
		{
			//output("收到数据<<"+e.data) ;
			if(m_aPkgReceive.Receive(this.m_aSocket))
			{
				// 包接收完毕
				if( ExternalInterface.available && m_sHandleReceive )
				{
					ExternalInterface.call(m_sHandleReceive,m_aPkgReceive.GetContent()) ;
				}
				
				output("接收数据<<"+m_aPkgReceive.GetContent()) ;
				
				// 重置包对象 预备介绍下一个包
				m_aPkgReceive.Reset() ;
			}
			
			// 检查 socket 中是否还有未读取完毕的消息， 多个包会同时到达
			var nByte:int = this.m_aSocket.bytesAvailable ;
			if(this.m_aSocket.bytesAvailable)
			{
				// 递归方式继续处理下一个包
				onPkgReceiver(e) ;
			}
			
		}
		private function onError(e:Event)
		{			
			if( ExternalInterface.available && m_sHandleError )
			{
				ExternalInterface.call(m_sHandleError) ;
			}
		}
		private function onSecurityError(e:Event)
		{			
			if( ExternalInterface.available && m_sHandleSecurityError )
			{
				ExternalInterface.call(m_sHandleSecurityError) ;
			}
		}
		
		public function send(sStream)
		{
			//m_aSocket.send(sStream+"\r\n") ;
			m_aSocket.writeMultiByte(sStream+"\r\n","UTF-8") ;
			m_aSocket.flush() ;
			
			output("发送数据>>"+sStream) ;
		}

		public function output(sText)
		{
			trace(sText) ;
			wndOutput.appendText(sText + "\r\n") ;
		}

		private var m_sRequest:String ;
		
		private var m_aSocket:Socket ;
		private var m_aPkgReceive = new PackageReceive() ;
		
		private var m_sHandleReceive:String = null ;
		private var m_sHandleConnect:String = null ;
		private var m_sHandleDisconnect:String = null ;
		private var m_sHandleError:String = null ;
		private var m_sHandleSecurityError:String = null ;
	}
	
	
}